{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I have always wanted to write a ufunc function in Python.  With Numba, you can --- and it will be fast."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Populating the interactive namespace from numpy and matplotlib\n"
     ]
    }
   ],
   "source": [
    "%pylab inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from numba import jit\n",
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define some polynomial evaluation tools."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "@jit('f8(f8,f8[:])', nopython=True)\n",
    "def polevl(x, coef):\n",
    "    N = len(coef)\n",
    "    ans = coef[0]\n",
    "    i = 1\n",
    "    while i < N:\n",
    "        ans = ans * x + coef[i]\n",
    "        i += 1\n",
    "    return ans\n",
    "\n",
    "@jit('f8(f8,f8[:])', nopython=True)\n",
    "def p1evl(x, coef):\n",
    "    N = len(coef)\n",
    "    ans = x + coef[0]\n",
    "    i = 1\n",
    "    while i < N:\n",
    "        ans = ans * x + coef[i]\n",
    "        i += 1\n",
    "    return ans    \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define some constants!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "PP = np.array([\n",
    "  7.96936729297347051624E-4,\n",
    "  8.28352392107440799803E-2,\n",
    "  1.23953371646414299388E0,\n",
    "  5.44725003058768775090E0,\n",
    "  8.74716500199817011941E0,\n",
    "  5.30324038235394892183E0,\n",
    "  9.99999999999999997821E-1], 'd')\n",
    "\n",
    "PQ = np.array([\n",
    "  9.24408810558863637013E-4,\n",
    "  8.56288474354474431428E-2,\n",
    "  1.25352743901058953537E0,\n",
    "  5.47097740330417105182E0,\n",
    "  8.76190883237069594232E0,\n",
    "  5.30605288235394617618E0,\n",
    "  1.00000000000000000218E0], 'd')\n",
    "  \n",
    "DR1 = 5.783185962946784521175995758455807035071\n",
    "DR2 = 30.47126234366208639907816317502275584842\n",
    "\n",
    "RP = np.array([\n",
    "-4.79443220978201773821E9,\n",
    " 1.95617491946556577543E12,\n",
    "-2.49248344360967716204E14,\n",
    " 9.70862251047306323952E15], 'd')\n",
    "\n",
    "RQ = np.array([\n",
    "    # 1.00000000000000000000E0,\n",
    " 4.99563147152651017219E2,\n",
    " 1.73785401676374683123E5,\n",
    " 4.84409658339962045305E7,\n",
    " 1.11855537045356834862E10,\n",
    " 2.11277520115489217587E12,\n",
    " 3.10518229857422583814E14,\n",
    " 3.18121955943204943306E16,\n",
    " 1.71086294081043136091E18], 'd')\n",
    "\n",
    "QP = np.array([\n",
    "-1.13663838898469149931E-2,\n",
    "-1.28252718670509318512E0,\n",
    "-1.95539544257735972385E1,\n",
    "-9.32060152123768231369E1,\n",
    "-1.77681167980488050595E2,\n",
    "-1.47077505154951170175E2,\n",
    "-5.14105326766599330220E1,\n",
    "-6.05014350600728481186E0], 'd')\n",
    "\n",
    "QQ = np.array([\n",
    "    # 1.00000000000000000000E0,\n",
    "  6.43178256118178023184E1,\n",
    "  8.56430025976980587198E2,\n",
    "  3.88240183605401609683E3,\n",
    "  7.24046774195652478189E3,\n",
    "  5.93072701187316984827E3,\n",
    "  2.06209331660327847417E3,\n",
    "  2.42005740240291393179E2], 'd')\n",
    "\n",
    "NPY_PI_4 = .78539816339744830962\n",
    "SQ2OPI  = .79788456080286535587989\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now for the function itself"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "@jit('f8(f8)')\n",
    "def j0(x):\n",
    "    if (x < 0):\n",
    "        x = -x\n",
    "\n",
    "    if (x <= 5.0):\n",
    "        z = x * x\n",
    "        if (x < 1.0e-5):\n",
    "            return (1.0 - z / 4.0)\n",
    "        p = (z-DR1) * (z-DR2)\n",
    "        p = p * polevl(z, RP) / polevl(z, RQ)\n",
    "        return p\n",
    "    \n",
    "    w = 5.0 / x\n",
    "    q = 25.0 / (x*x)\n",
    "    p = polevl(q, PP) / polevl(q, PQ)\n",
    "    q = polevl(q, QP) / p1evl(q, QQ)\n",
    "    xn = x - NPY_PI_4\n",
    "    p = p*math.cos(xn) - w * q * math.sin(xn)\n",
    "    return p * SQ2OPI / math.sqrt(x)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from numba import vectorize\n",
    "import scipy.special as ss\n",
    "\n",
    "vj0 = vectorize(['f8(f8)'])(j0.py_func)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "x = np.linspace(-10,10,1000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "100 loops, best of 3: 4.47 ms per loop\n"
     ]
    }
   ],
   "source": [
    "%timeit vj0(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The slowest run took 11.78 times longer than the fastest. This could mean that an intermediate result is being cached.\n",
      "10000 loops, best of 3: 28.4 µs per loop\n"
     ]
    }
   ],
   "source": [
    "%timeit ss.j0(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x10f0b49b0>,\n",
       " <matplotlib.lines.Line2D at 0x10f0b4f28>]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10f4d44a8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot(x, vj0(x), x, ss.j0(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This was run on a Macbook Air.   Running `sysctl -n machdep.cpu.brand_string` resulted in:\n",
    "\n",
    "  Intel(R) Core(TM) i7-3720QM CPU @ 2.60GHz"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
